////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001-2010.
// -------------------------------------------------------------------------
//  File name:   ScriptBind_UIAction.h
//  Version:     v1.00
//  Created:     10/9/2010 by Paul Reindell.
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __SCRIPTBIND_UIACTION_H__
#define __SCRIPTBIND_UIACTION_H__

#pragma once

#include <IScriptSystem.h>
#include <ScriptHelpers.h>
#include <IFlashUI.h>
#include <CryListenerSet.h>

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
struct SUIToLuaConversationHelper
{
	static ScriptAnyValue UIValueToLuaValue(const TUIData& value, bool& ok);
	static bool LuaTableToUIArgs(SmartScriptTable table, SUIArguments &args);
	static bool LuaArgsToUIArgs(IFunctionHandler* pH, int startIdx, SUIArguments &args);
	static bool LuaArgToUIArg(IFunctionHandler* pH, int idx, TUIData &value);
	static bool UIArgsToLuaTable(const SUIArguments &args, SmartScriptTable table);
};

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
template<class T> struct SUILuaCallbackInfo
{
	bool Accept(const SUILuaCallbackInfo<T>& info) const { assert(false); }
	void CallScript(SmartScriptTable pScript, const char* functionName, SmartScriptTable args, const SUILuaCallbackInfo<T>& info) const { assert(false); }
};

////////////////////////////////////////////////////////////////////////////
template<class T>
struct SUILuaCallbackData
{
	SUILuaCallbackData(SmartScriptTable pTable, int id, const char* functionName, const SUILuaCallbackInfo<T>& cbinfo)
		: pScriptTable(pTable)
		, Id(id)
		, fctName(functionName)
		, info(cbinfo)
	{
	}
	int Id;
	SmartScriptTable pScriptTable;
	string fctName;
	SUILuaCallbackInfo<T> info;
};

////////////////////////////////////////////////////////////////////////////
struct SUISUILuaCallbackDataId
{
	static int GetNextId()
	{
		static int id = 0;
		++id;
		assert(id > 0); 
		return id;
	}
};

template<class T>
struct SUILuaCallbackContainer : public SUISUILuaCallbackDataId
{
	SUILuaCallbackContainer() : m_Callbacks(10) {}
	bool AddCallback(SmartScriptTable pTable, const char* functionName, const SUILuaCallbackInfo<T>& cbinfo)
	{
		int id = -1;
		pTable->GetValue("__ui_callback_id", id);
		if (id > -1)
		{
			for (typename TCallbacks::Notifier it(m_Callbacks); it.IsValid(); it.Next())
			{
				SUILuaCallbackData<T>* pListener = *it;
				if (pListener->Id == id && pListener->fctName == functionName && pListener->info.Accept(cbinfo))
					return false;
			}
		}
		else
		{
			id = GetNextId();
			pTable->SetValue("__ui_callback_id", id);
		}
		m_Callbacks.Add(new SUILuaCallbackData<T>(pTable, id, functionName, cbinfo));
		return true;
	}

	bool RemoveCallbacks(SmartScriptTable pTable, const char* functionName = "")
	{
		bool bErased = false;
		int id = -1;
		pTable->GetValue("__ui_callback_id", id);
		if (id > -1)
		{
			for (typename TCallbacks::Notifier it(m_Callbacks); it.IsValid(); it.Next())
			{
				SUILuaCallbackData<T>* pListener = *it;
				if (pListener->Id == id && (strlen(functionName) == 0 || pListener->fctName == functionName))
				{
					m_Callbacks.Remove(pListener);
					delete pListener;
				}
			}
		}
		return bErased;
	}

	bool IsEnabled(SmartScriptTable pTable)
	{
		bool bEnabled = true;
		const char* name;
		if (pTable->GetValue("__ui_action_name", name) && strlen(name) > 0)
			bEnabled &= pTable->GetValue("enabled", bEnabled);
		return bEnabled;
	}

	void ClearCallbacks()
	{
		for (typename TCallbacks::Notifier it(m_Callbacks); it.IsValid(); it.Next())
			delete *it;
		m_Callbacks.Clear();
	}

protected:
	void NotifyEvent(const SUILuaCallbackInfo<T>& cbinfo, const SUIArguments& args = SUIArguments())
	{
		SmartScriptTable table = gEnv->pScriptSystem->CreateTable();
		SUIToLuaConversationHelper::UIArgsToLuaTable(args, table);

		for (typename TCallbacks::Notifier it(m_Callbacks); it.IsValid(); it.Next())
		{
			SUILuaCallbackData<T>* pListener = *it;
			if (pListener->info.Accept(cbinfo) && IsEnabled(pListener->pScriptTable))
				pListener->info.CallScript(pListener->pScriptTable, pListener->fctName, table, cbinfo);
		}
	}

private:
	typedef CListenerSet< SUILuaCallbackData<T>* > TCallbacks;
	TCallbacks m_Callbacks;
};

////////////////////////////////////////////////////////////////////////////
/////////////////////////////// IUIElement /////////////////////////////////
////////////////////////////////////////////////////////////////////////////
template<>
struct SUILuaCallbackInfo<IUIElement>
{
	static SUILuaCallbackInfo<IUIElement> CreateInfo(IUIElement* pElement, const char* eventName, int instanceId = -2)
	{
		SUILuaCallbackInfo<IUIElement> res;
		res.eventName = eventName;
		res.elementName = pElement ? pElement->GetName() : "";
		res.instanceId = instanceId > -2 ? instanceId : pElement->GetInstanceID();
		return res;
	}

	bool Accept(const SUILuaCallbackInfo<IUIElement>& info) const
	{
		return (elementName == "" || info.elementName == elementName) && (eventName == "" || info.eventName == eventName) && (instanceId == -1 || instanceId == info.instanceId);
	}

	void CallScript(SmartScriptTable pScript, const char* functionName, SmartScriptTable args, const SUILuaCallbackInfo<IUIElement>& info) const
	{
		Script::CallMethod(pScript, functionName, info.elementName.c_str(), info.instanceId, info.eventName.c_str(), args);
	}

	int instanceId;
	string eventName;
	string elementName;
};

////////////////////////////////////////////////////////////////////////////
struct SUIElementLuaCallback : public SUILuaCallbackContainer<IUIElement>, public IUIElementEventListener
{
	~SUIElementLuaCallback();

	void Init(IUIElement* pElement);
	void Clear();

	virtual void OnUIEvent( IUIElement* pSender, const SUIEventDesc& event, const SUIArguments& args );
	virtual void OnUIEventEx( IUIElement* pSender, const char* fscommand, const SUIArguments& args, void* pUserData );

	virtual void OnInit( IUIElement* pSender, IFlashPlayer* pFlashPlayer );
	virtual void OnUnload( IUIElement* pSender);
	virtual void OnSetVisible(  IUIElement* pSender, bool bVisible );

	virtual void OnInstanceCreated( IUIElement* pSender, IUIElement* pNewInstance );
	virtual void OnInstanceDestroyed( IUIElement* pSender, IUIElement* pDeletedInstance );
};

////////////////////////////////////////////////////////////////////////////
//////////////////////////////// IUIAction /////////////////////////////////
////////////////////////////////////////////////////////////////////////////
template<>
struct SUILuaCallbackInfo<IUIAction>
{
	static SUILuaCallbackInfo<IUIAction> CreateInfo(IUIAction* pAction, const char* eventName)
	{
		SUILuaCallbackInfo<IUIAction> res;
		res.eventName = eventName;
		res.actionName = pAction ? pAction->GetName() : "";
		return res;
	}

	bool Accept(const SUILuaCallbackInfo<IUIAction>& info) const
	{
		return (actionName == "" || info.actionName == actionName) && (eventName == "" || info.eventName == eventName);
	}

	void CallScript(SmartScriptTable pScript, const char* functionName, SmartScriptTable args, const SUILuaCallbackInfo<IUIAction>& info) const
	{
		Script::CallMethod(pScript, functionName, info.actionName.c_str(), info.eventName.c_str(), args);
	}

	string eventName;
	string actionName;
};

struct SUIActionLuaCallback : public SUILuaCallbackContainer<IUIAction>, public IUIActionListener
{
	SUIActionLuaCallback();
	~SUIActionLuaCallback();

	void Clear();

	virtual void OnStart( IUIAction* pAction, const SUIArguments& args );
	virtual void OnEnd( IUIAction* pAction, const SUIArguments& args );
};

////////////////////////////////////////////////////////////////////////////
///////////////////////////// IUIEventSystem ///////////////////////////////
////////////////////////////////////////////////////////////////////////////
template<>
struct SUILuaCallbackInfo<IUIEventSystem>
{
	static SUILuaCallbackInfo<IUIEventSystem> CreateInfo(IUIEventSystem* pEventSystem, const char* eventName)
	{
		SUILuaCallbackInfo<IUIEventSystem> res;
		res.eventName = eventName;
		res.eventSystemName = pEventSystem ? pEventSystem->GetName() : "";
		return res;
	}

	bool Accept(const SUILuaCallbackInfo<IUIEventSystem>& info) const
	{
		return (eventSystemName == "" || info.eventSystemName == eventSystemName) && (eventName == "" || info.eventName == eventName);
	}

	void CallScript(SmartScriptTable pScript, const char* functionName, SmartScriptTable args, const SUILuaCallbackInfo<IUIEventSystem>& info) const
	{
		Script::CallMethod(pScript, functionName, info.eventSystemName.c_str(), info.eventName.c_str(), args);
	}

	string eventName;
	string eventSystemName;
};

struct SUIEventSystemLuaCallback : public SUILuaCallbackContainer<IUIEventSystem>
{
	~SUIEventSystemLuaCallback();

	void Init(IUIEventSystem* pEventSystem);
	void Clear();
	void OnEvent( IUIEventSystem* pEventSystem, const SUIEvent& event );

private:
	void AddNewListener(IUIEventSystem* pEventSystem);

	struct SEventSystemListener : public IUIEventListener
	{
		SEventSystemListener() : m_pEventSystem(NULL) {}
		SEventSystemListener(IUIEventSystem* pEventSystem, SUIEventSystemLuaCallback* pOwner) { Init(pEventSystem, pOwner); }
		SEventSystemListener(const SEventSystemListener& other) { Init(other.m_pEventSystem, other.m_pOwner); }
		SEventSystemListener& operator=(const SEventSystemListener& other) { Clear(); Init(other.m_pEventSystem, other.m_pOwner); return *this; }
		~SEventSystemListener();

		virtual SUIArgumentsRet OnEvent( const SUIEvent& event );
		virtual void OnEventSystemDestroyed(IUIEventSystem* pEventSystem);

		IUIEventSystem* GetEventSystem() const { return m_pEventSystem; }

	private:
		void Init(IUIEventSystem* pEventSystem, SUIEventSystemLuaCallback* pOwner);
		void Clear();
		IUIEventSystem* m_pEventSystem;
		SUIEventSystemLuaCallback* m_pOwner;
	};
	typedef std::vector<SEventSystemListener> TListener;
	TListener m_Listener;
};


////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
class CScriptBind_UIAction
	:	public CScriptableBase
	, public IUIModule
{
public:
	CScriptBind_UIAction();
	virtual ~CScriptBind_UIAction();

	void Release() { delete this; };

	virtual void GetMemoryUsage(ICrySizer *pSizer) const
	{
		pSizer->AddObject(this, sizeof(*this));
	}

	// <title ReloadElement>
	// Syntax: UIAction.ReloadElement(const char * elementName, int instanceID )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	// Description:
	//		Reloads the UI flash asset.
	int ReloadElement( IFunctionHandler *pH, const char * elementName, int instanceID );

	// <title UnloadElement>
	// Syntax: UIAction.UnloadElement(const char * elementName, int instanceID )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	// Description:
	//		Unloads the UI flash asset.
	int UnloadElement( IFunctionHandler *pH, const char * elementName, int instanceID );

	// <title ShowElement>
	// Syntax: UIAction.ShowElement(const char * elementName, int instanceID )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	// Description:
	//		Displays the UI flash asset.
	int ShowElement( IFunctionHandler *pH, const char * elementName, int instanceID );

	// <title HideElement>
	// Syntax: UIAction.HideElement(const char * elementName, int instanceID )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	// Description:
	//		Hide the UI flash asset.
	int HideElement( IFunctionHandler *pH, const char * elementName, int instanceID );

	// <title SoftHideElement>
	// Syntax: UIAction.RequestHide(const char * elementName, int instanceID )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	// Description:
	//		Send the fade out signal to the UI flash asset.
	int RequestHide( IFunctionHandler *pH, const char * elementName, int instanceID );

	// <title CallFunction>
	// Syntax: UIAction.CallFunction(const char * elementName, int instanceID, const char* functionName, [arg1], [arg2], [...] )
	// Arguments:
	//		elementName - UI Element name as defined in the xml or UIEventSystem name as defined via cpp.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances. If used on UIEventSystem no instance id is ignored
	//		functionName - Function or event name.
	//		args - List of arguments (optional)
	// Description:
	//		Calls a function of the UI flash asset or the UIEventSystem.
	int CallFunction( IFunctionHandler *pH, const char * elementName, int instanceID, const char* functionName );

	// <title SetVariable>
	// Syntax: UIAction.SetVariable(const char * elementName, int instanceID, const char * varName, value )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		varName - Variable name as defined in the xml.
	//		value - Value to set.
	// Description:
	//		Sets a variable of the UI flash asset.
	int SetVariable( IFunctionHandler *pH, const char * elementName, int instanceID, const char * varName );

	// <title GetVariable>
	// Syntax: UIAction.GetVariable(const char * elementName, int instanceID, const char * varName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		varName - Variable name as defined in the xml.
	// Description:
	//		Gets a variable of the UI flash asset.
	int GetVariable( IFunctionHandler *pH, const char * elementName, int instanceID, const char * varName );

	// <title SetArray>
	// Syntax: UIAction.SetArray(const char * elementName, int instanceID, const char * arrayName, SmartScriptTable values )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		arrayName - Array name as defined in the xml.
	//		values - Table of values for the array.
	// Description:
	//		Sets an array of the UI flash asset.
	int SetArray( IFunctionHandler *pH, const char * elementName, int instanceID, const char * arrayName, SmartScriptTable values );

	// <title GetArray>
	// Syntax: UIAction.GetArray(const char * elementName, int instanceID, const char * arrayName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		arrayName - Array name as defined in the xml.
	// Description:
	//		Returns a table with values of the array.
	int GetArray( IFunctionHandler *pH, const char * elementName, int instanceID, const char * arrayName );

	// <title GotoAndPlay>
	// Syntax: UIAction.GotoAndPlay(const char * elementName, int instanceID, const char * mcName, int frameNum )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		frameNum - frame number.
	// Description:
	//		Call GotoAndPlay on a MovieClip.
	int GotoAndPlay( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, int frameNum );

	// <title GotoAndStop>
	// Syntax: UIAction.GotoAndStop(const char * elementName, int instanceID, const char * mcName, int frameNum )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		frameNum - frame number.
	// Description:
	//		Call GotoAndStop on a MovieClip.
	int GotoAndStop( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, int frameNum );

	// <title GotoAndPlayFrameName>
	// Syntax: UIAction.GotoAndPlayFrameName( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, const char * frameName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		frameName - frame name.
	// Description:
	//		Call GotoAndPlay on a MovieClip by frame name.
	int GotoAndPlayFrameName( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, const char * frameName );

	// <title GotoAndStopFrameName>
	// Syntax: UIAction.GotoAndStopFrameName( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, const char * frameName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		frameName - frame name.
	// Description:
	//		Call GotoAndStop on a MovieClip by frame name.
	int GotoAndStopFrameName( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, const char * frameName );

	// <title SetAlpha>
	// Syntax: UIAction.SetAlpha( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, float fAlpha )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		fAlpha - alpha value (0-1).
	// Description:
	//		Set MovieClip alpha value.
	int SetAlpha( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, float fAlpha );

	// <title GetAlpha>
	// Syntax: UIAction.GetAlpha( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	// Description:
	//		Get MovieClip alpha value.
	int GetAlpha( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName );

	// <title SetVisible>
	// Syntax: UIAction.SetVisible( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, float bVisible )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		bVisible - visible.
	// Description:
	//		Set MovieClip visible state.
	int SetVisible( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, bool bVisible );

	// <title IsVisible>
	// Syntax: UIAction.IsVisible( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	// Description:
	//		Get MovieClip visible state.
	int IsVisible( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName );

	// <title SetPos>
	// Syntax: UIAction.SetPos( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vPos  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		vPos - position.
	// Description:
	//		Set MovieClip position.
	int SetPos( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vPos );

	// <title GetPos>
	// Syntax: UIAction.GetPos( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	// Description:
	//		Get MovieClip position.
	int GetPos( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName );

	// <title SetRotation>
	// Syntax: UIAction.SetRotation( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vRotation  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		vRotation - rotation.
	// Description:
	//		Set MovieClip rotation.
	int SetRotation( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vRotation );

	// <title GetRotation>
	// Syntax: UIAction.GetRotation( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	// Description:
	//		Get MovieClip rotation.
	int GetRotation( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName );

	// <title SetScale>
	// Syntax: UIAction.SetScale( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vScale  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	//		vScale - scale.
	// Description:
	//		Set MovieClip scale.
	int SetScale( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName, Vec3 vScale );

	// <title GetScale>
	// Syntax: UIAction.GetScale( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName  )
	// Arguments:
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		mcName - MovieClip name as defined in the xml.
	// Description:
	//		Get MovieClip scale.
	int GetScale( IFunctionHandler *pH, const char * elementName, int instanceID, const char * mcName );


	// <title StartAction>
	// Syntax: UIAction.StartAction(const char * actionName, SmartScriptTable arguments )
	// Arguments:
	//		actionName - UI Action name.
	//		arguments - arguments to pass to this action.
	// Description:
	//		Starts an UI Action.
	int StartAction( IFunctionHandler *pH, const char * actionName, SmartScriptTable arguments );

	// <title StartAction>
	// Syntax: UIAction.EndAction(SmartScriptTable table, bool disable, SmartScriptTable arguments )
	// Arguments:
	//		table - must be "self"
	//		disable - if true this action gets disabled on end.
	//		arguments - arguments to return from this action.
	// Description:
	//		Ends an UI Action. This can be only used withing a UIAction Lua script!
	int EndAction( IFunctionHandler *pH, SmartScriptTable pTable, bool disable, SmartScriptTable arguments );

	// <title EnableAction>
	// Syntax: UIAction.EnableAction(const char * actionName )
	// Arguments:
	//		actionName - UI Action name.
	// Description:
	//		Enables an UI Action.
	int EnableAction( IFunctionHandler *pH, const char * actionName );

	// <title DisableAction>
	// Syntax: UIAction.DisableAction(const char * actionName )
	// Arguments:
	//		actionName - UI Action name.
	// Description:
	//		Disables an UI Action.
	int DisableAction( IFunctionHandler *pH, const char * actionName );

	// <title RegisterElementListener>
	// Syntax: UIAction.RegisterElementListener(SmartScriptTable table, const char * elementName, int instanceID, const char * eventName, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		elementName - UI Element name as defined in the xml.
	//		instanceID - ID of the instance (if instance with id does not exist, it will be created). '-1' for all instances
	//		eventName - Name of the event that is fired from the UI Element - if empty string it will receive all events!
	//		callbackFunctionName - name of the script function that will receive the callback.
	// Description:
	//		Register a callback function for an UIElement event.
	//		Callback Function must have form: CallbackName(elementName, instanceId, eventName, argTable)
	int RegisterElementListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* elementName, int instanceID, const char* eventName, const char* callback );

	// <title RegisterActionListener>
	// Syntax: UIAction.RegisterActionListener(SmartScriptTable table, const char * actionName, const char * eventName, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		actionName - UI Action name
	//		eventName - Name of the event that is fired from the UI Action (can be "OnStart" or "OnEnd") - if empty string it will receive all events!
	//		callbackFunctionName - name of the script function that will receive the callback.
	// Description:
	//		Register a callback function for an UIAction event.
	//		Callback Function must have form: CallbackName(actionName, eventName, argTable)
	int RegisterActionListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* actionName, const char* eventName, const char* callback );

	// <title RegisterEventSystemListener>
	// Syntax: UIAction.RegisterEventSystemListener(SmartScriptTable table, const char * eventSystem, const char * eventName, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		eventSystem - UI Event System name
	//		eventName - Name of the event that is fired from the UI EventSystem - if empty string it will receive all events!
	//		callbackFunctionName - name of the script function that will receive the callback.
	// Description:
	//		Register a callback function for an UIEventSystem event.
	//		Callback Function must have form: CallbackName(actionName, eventName, argTable)
	int RegisterEventSystemListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* eventSystem, const char* eventName, const char* callback );

	// <title UnregisterElementListener>
	// Syntax: UIAction.UnregisterElementListener(SmartScriptTable table, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		callbackFunctionName - name of the script function that receives the callback. if "" all callbacks for this script will be removed
	// Description:
	//		Unregister callback functions for an UIElement event.
	int UnregisterElementListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* callback );

	// <title UnregisterActionListener>
	// Syntax: UIAction.UnregisterActionListener(SmartScriptTable table, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		callbackFunctionName - name of the script function that receives the callback. if "" all callbacks for this script will be removed
	// Description:
	//		Unregister callback functions for an UIAction event.
	int UnregisterActionListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* callback );

	// <title UnregisterEventSystemListener>
	// Syntax: UIAction.UnregisterEventSystemListener(SmartScriptTable table, const char * callbackFunctionName )
	// Arguments:
	//		table - the script that receives the callback (can be "self" to refer the current script).
	//		callbackFunctionName - name of the script function that receives the callback. if "" all callbacks for this script will be removed
	// Description:
	//		Unregister callback functions for an UIEventSystem event.
	int UnregisterEventSystemListener( IFunctionHandler *pH, SmartScriptTable pTable, const char* callback );

	// IUIModule
	virtual void Reload();
	virtual void Reset();
	// ~IUIModule

private:
	void RegisterMethods();

	IUIElement* GetElement( const char* sName, int instanceID, bool bSupressWarning = false );
	IUIAction*  GetAction( const char* sName );
	IUIEventSystem* GetEventSystem( const char* sName, IUIEventSystem::EEventSystemType type );

	SUIElementLuaCallback	m_ElementCallbacks;
 	SUIActionLuaCallback m_ActionCallbacks;
	SUIEventSystemLuaCallback m_EventSystemCallbacks;
};

#endif // #ifndef __SCRIPTBIND_UIACTION_H__
